From ef8c651af1ce84ac1f4c6cc383f92a48762842b0 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 19 May 2015 22:50:26 -0700 Subject: [PATCH] Don't update the same path source multiple times Updating a path source can be a possibly expensive operation (lots of directories that need to be traversed), and currently the root path source is updated three times: * Once when the root package is initially loaded. * Again when the first resolution pass happens over a graph. * Finally a third when the second resolution pass happens over the graph. This commit pushes through the original `Source` trait object into the `PackageRegistry` and removes the implicit call to `add_sources`, pushing that call up to the stack a bit. --- src/cargo/core/registry.rs | 5 +++++ src/cargo/ops/cargo_compile.rs | 9 ++++++++- src/cargo/ops/cargo_fetch.rs | 1 + src/cargo/ops/cargo_generate_lockfile.rs | 2 ++ src/cargo/ops/cargo_package.rs | 2 +- src/cargo/ops/resolve.rs | 2 -- src/cargo/sources/path.rs | 1 - 7 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/cargo/core/registry.rs b/src/cargo/core/registry.rs index 3bd5e6a60..4bd13c29e 100644 --- a/src/cargo/core/registry.rs +++ b/src/cargo/core/registry.rs @@ -140,6 +140,11 @@ impl<'cfg> PackageRegistry<'cfg> { Ok(()) } + pub fn preload(&mut self, id: &SourceId, source: Box) { + self.sources.insert(id, source); + self.source_ids.insert(id.clone(), (id.clone(), Kind::Locked)); + } + pub fn add_sources(&mut self, ids: &[SourceId]) -> CargoResult<()> { for id in ids.iter() { try!(self.load(id, Kind::Locked)); diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 26db527dc..a92720804 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -98,10 +98,11 @@ pub fn compile<'a>(manifest_path: &Path, for key in package.manifest().warnings().iter() { try!(options.config.shell().warn(key)) } - compile_pkg(&package, options) + compile_pkg(&package, Some(Box::new(source)), options) } pub fn compile_pkg<'a>(package: &Package, + source: Option>, options: &CompileOptions<'a>) -> CargoResult> { let CompileOptions { config, jobs, target, spec, features, @@ -127,6 +128,12 @@ pub fn compile_pkg<'a>(package: &Package, let (packages, resolve_with_overrides, sources) = { let rustc_host = config.rustc_host().to_string(); let mut registry = PackageRegistry::new(config); + if let Some(source) = source { + registry.preload(package.package_id().source_id(), source); + } else { + try!(registry.add_sources(&[package.package_id().source_id() + .clone()])); + } // First, resolve the package's *listed* dependencies, as well as // downloading and updating all remotes and such. diff --git a/src/cargo/ops/cargo_fetch.rs b/src/cargo/ops/cargo_fetch.rs index d4faeffcd..cbd3382f9 100644 --- a/src/cargo/ops/cargo_fetch.rs +++ b/src/cargo/ops/cargo_fetch.rs @@ -14,6 +14,7 @@ pub fn fetch(manifest_path: &Path, config: &Config) -> CargoResult<()> { let package = try!(source.root_package()); let mut registry = PackageRegistry::new(config); + registry.preload(package.package_id().source_id(), Box::new(source)); let resolve = try!(ops::resolve_pkg(&mut registry, &package)); let ids: Vec = resolve.iter().cloned().collect(); diff --git a/src/cargo/ops/cargo_generate_lockfile.rs b/src/cargo/ops/cargo_generate_lockfile.rs index e12010439..534a7cdc5 100644 --- a/src/cargo/ops/cargo_generate_lockfile.rs +++ b/src/cargo/ops/cargo_generate_lockfile.rs @@ -24,6 +24,7 @@ pub fn generate_lockfile(manifest_path: &Path, config: &Config) try!(source.update()); let package = try!(source.root_package()); let mut registry = PackageRegistry::new(config); + registry.preload(package.package_id().source_id(), Box::new(source)); let resolve = try!(ops::resolve_with_previous(&mut registry, &package, Method::Everything, None, None)); @@ -84,6 +85,7 @@ pub fn update_lockfile(manifest_path: &Path, None => to_avoid.extend(previous_resolve.iter()), } + registry.preload(package.package_id().source_id(), Box::new(source)); let resolve = try!(ops::resolve_with_previous(&mut registry, &package, Method::Everything, diff --git a/src/cargo/ops/cargo_package.rs b/src/cargo/ops/cargo_package.rs index 892512d54..ccae355de 100644 --- a/src/cargo/ops/cargo_package.rs +++ b/src/cargo/ops/cargo_package.rs @@ -178,7 +178,7 @@ fn run_verify(config: &Config, pkg: &Package, tar: &Path) let new_pkg = Package::new(new_manifest, &manifest_path, &new_src); // Now that we've rewritten all our path dependencies, compile it! - try!(ops::compile_pkg(&new_pkg, &ops::CompileOptions { + try!(ops::compile_pkg(&new_pkg, None, &ops::CompileOptions { config: config, jobs: None, target: None, diff --git a/src/cargo/ops/resolve.rs b/src/cargo/ops/resolve.rs index 6ec6a6a15..2d638d5cc 100644 --- a/src/cargo/ops/resolve.rs +++ b/src/cargo/ops/resolve.rs @@ -36,8 +36,6 @@ pub fn resolve_with_previous<'a>(registry: &mut PackageRegistry, previous: Option<&'a Resolve>, to_avoid: Option<&HashSet<&'a PackageId>>) -> CargoResult { - let root = package.package_id().source_id().clone(); - try!(registry.add_sources(&[root])); // Here we place an artificial limitation that all non-registry sources // cannot be locked at more than one revision. This means that if a git diff --git a/src/cargo/sources/path.rs b/src/cargo/sources/path.rs index 16681226e..fe886c258 100644 --- a/src/cargo/sources/path.rs +++ b/src/cargo/sources/path.rs @@ -59,7 +59,6 @@ impl<'cfg> PathSource<'cfg> { } pub fn read_packages(&self) -> CargoResult> { - if self.updated { Ok(self.packages.clone()) } else if self.id.is_path() && self.id.precise().is_some() { -- 2.30.2